package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
//操作了两张表，那么为了保证数据的一致性，我们需要在方法上加上注解 @Transactional来控制事务。
@Service
@Transactional
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;
    //新增菜品，同时插入菜品对应的口味数据，需要操作两张表：dish、dish_flavor
    public void saveWithFlavor(@RequestBody DishDto dishDto) {
        //页面传递的菜品口味信息，仅仅包含name 和 value属性，缺少一个非常重要的属性dishId，
        // 所以在保存完菜品的基本信息后，我们需要获取到菜品ID，然后为菜品口味对象属性dishId赋值
        /**
         * ①. 保存菜品基本信息 ;
         *
         * ②. 获取保存的菜品ID ;
         *
         * ③. 获取菜品口味列表，遍历列表，为菜品口味对象属性dishId赋值;
         *
         * ④. 批量保存菜品口味列表;
         */
        //①. 保存菜品基本信息到菜品表dish ;
        this.save(dishDto);
        //获取菜品id
        Long dishId = dishDto.getId();
        //③. 获取菜品口味列表，遍历列表，为菜品口味对象属性dishId赋值;
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishId);
        }
        //上面这段代码可以替代下面这段代码,既简单 可读性也强
//         flavors = flavors.stream().map((item) -> {
//                    item.setDishId(dishId);
//                    return item;
//                }
//        ).collect(Collectors.toList());

//④. 批量保存菜品口味列表;
        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 2). 在DishService实现类中实现此方法
     *
     * 具体逻辑为:
     *
     * A. 根据ID查询菜品的基本信息
     *
     * B. 根据菜品的ID查询菜品口味列表数据
     *
     * C. 组装数据并返回
     * @param id
     * @return
     */

    public DishDto getByIdWithFlavor(Long id) {
        ////查询菜品基本信息，从dish表查询
        Dish dish = this.getById(id);
        //创建dto对象
        DishDto dishDto = new DishDto();
        //将dish中的数据传给dishDto
        BeanUtils.copyProperties(dish,dishDto);
        //查询当前菜品对应的口味信息 从dish_flavor表中查询
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        log.info("{}",id);
        log.info("{}",dish.getId());
        //经过两次打印我们知道id是一样的
        dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId,id);//这里笔记里写的是dish.getId()
        List<DishFlavor> list = dishFlavorService.list(dishFlavorLambdaQueryWrapper);



        return dishDto;
    }

    /**
     * 在该方法中,我们既需要更新dish菜品基本信息表,还需要更新dish_flavor菜品口味表
     * 而页面操作时,有修改 有新增 也有可能删除我们只需要保持一个原则先删除 后添加
     * @param dishDto
     */
    @Override
    @Transactional//因为操作的是两张表所以要加上这个注解
    public void updateWithFlavor(DishDto dishDto) {
        //更新dish表基本信息
        this.updateById(dishDto);
        //清理当前菜品对应口味数据    dish_flavor表的delete操作
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId,dishDto.getId());
        dishFlavorService.remove(dishFlavorLambdaQueryWrapper);
        //添加当前提交过来的口味数据 dish_flavor的insert操作
        List<DishFlavor> flavors = dishDto.getFlavors();
        //将id赋值给口味中中的数据
        flavors = flavors.stream().map((item)->{
            item.setDishId(dishDto.getId());//它自己的id是自动生成的
            return item;
                }).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavors);


    }

    //事务控制
    @Transactional
    public void del(String[] ids) {
        //根据dish_id批量删除口味信息
        QueryWrapper<DishFlavor> dishFlavorQueryWrapper = new QueryWrapper<>();//这里为什么不能用LamdaQueryWrapper
        dishFlavorQueryWrapper.in("dish_id", Arrays.asList(ids));
        dishFlavorService.remove(dishFlavorQueryWrapper);

        //删除菜品信息
        this.removeByIds(Arrays.asList(ids));


    }
}
